#include <windows.h>
#include <assert.h>

HGLOBAL ghMoveMem;

DWORD WINAPI threadFunc1(LPVOID para) {
	PVOID pMem;
	pMem = GlobalLock(ghMoveMem);
	assert(ghMoveMem);

	sprintf(pMem, "thread id: %u, para: %u\n", GetCurrentThreadId(), para);
	printf(pMem);

	GlobalUnlock(ghMoveMem);
	return 0;
}

int main(void) {
	// global moveable mem + thread
	{
		PVOID pMem;
		HGLOBAL hMoveMemNew, hMoveMem = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, 0);
		assert(hMoveMem);

		hMoveMemNew = GlobalReAlloc(hMoveMem, 1024, GMEM_MOVEABLE | GMEM_ZEROINIT);
		assert(hMoveMemNew);

		ghMoveMem = hMoveMemNew;

		pMem = GlobalLock(hMoveMem);
		assert(pMem);
		sprintf(pMem, "hello world");
		GlobalUnlock(hMoveMem);

		// thread test
		{
			HANDLE threadList[32];
			int i;
			for (i = 0; i < 32; ++i) {
				threadList[i] = _beginthreadex(0, 0, threadFunc1, i, 0, 0);
				assert(threadList[i]);
			}

			for (i = 0; i < 32; ++i) {
				WaitForSingleObject(threadList[i], INFINITE);
				CloseHandle(threadList[i]);
			}
		}

		printf("%u\n", GlobalSize(hMoveMem));
		GlobalFree(hMoveMem);
	}
	return 0;
}
